//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Logging Application Block
//===============================================================================
//  LogParser - Log File Parser
//  Copyright (C) 2007  Alois Kraus
//  
//  This source code is published under the Microsoft Permissive License (Ms-PL)
//  http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx
//===============================================================================

using System;
using Microsoft.Practices.EnterpriseLibrary.Logging;

namespace EntLibContrib.Logging.Parser
{
	/// <summary>
	/// The filter is used with a Reader instance to get only the log events you are interested in. 
	/// A log message does only match if all properties of the Filter do produce a positive match (logical and).
	/// Empty or null properties (e.g. Messsages) are ignored and not considered in the match.
	/// </summary>
	public class Filter
	{
		#region Fields
		private DateTime myStartTime;
		private DateTime myStopTime;
		private string[] myMessages;
		#endregion

		#region Properties
		/// <summary>
		/// All messages which where written after the start time do match. Use this property with StopTime to 
		/// specify a time interval for the messages you are interested in.
		/// </summary>
		/// <value>The start time.</value>
		public DateTime StartTime
		{
			get { return myStartTime; }
			set { myStartTime = value; }
		}

		/// <summary>
		/// All messages which are younger than the stop time do match. Use this property with StartTime to 
		/// specify a time interval for the messages you are interested in.
		/// </summary>
		/// <value>The stop time.</value>
		public DateTime StopTime
		{
			get { return myStopTime; }
			set { myStopTime = value; }
		}

		/// <summary>
		/// Will match if a log message if one substring match with the string in the Messages array does succed.
		/// A null or empty Messages array does always match.
		/// </summary>
		/// <value>The messages.</value>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
		public string[] Messages
		{
			get { return myMessages; }
			set { myMessages = value; }
		}
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="Filter"/> class.
		/// </summary>
		public Filter()
		{
			myStartTime = DateTime.MinValue;
			myStopTime = DateTime.MaxValue;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Filter"/> class.
		/// </summary>
		/// <param name="startTime">The start time.</param>
		public Filter(DateTime startTime)
		{
			myStartTime = startTime;
			myStopTime = DateTime.MaxValue;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Filter"/> class.
		/// </summary>
		/// <param name="startTime">The start time.</param>
		/// <param name="stopTime">The stop time.</param>
		public Filter(DateTime startTime, DateTime stopTime)
		{
			myStartTime = startTime;
			myStopTime = stopTime;
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Checks if the LogEntry does pass the filter.
		/// </summary>
		/// <param name="entry">The log entry.</param>
		/// <returns>
		/// true if the entry has passed the filter. false otherwise.
		/// </returns>
		/// <exception cref="ArgumentNullException">If the entry argument is null.</exception>
		public bool Match(LogEntry entry)
		{
			if (entry == null)
				throw new ArgumentNullException("entry");

			if (entry.TimeStamp >= StartTime && entry.TimeStamp <= StopTime)
				return MatchMessage(entry);

			return false;
		}
		#endregion

		#region Private Methods
		private bool MatchMessage(LogEntry entry)
		{
			if (Messages == null || Messages.Length == 0)
				return true;

			foreach (string msg in Messages)
			{
				if (entry.Message.Contains(msg))
					return true;
			}

			return false;
		}
		#endregion
	}
}
